package com.wps.wdztv6.utils;

import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

@Log4j2
public class WPS4Util {

    public final static String HTTP_HEADER_WPS_DOCS_DATE = "Wps-Docs-Date";
    public final static String HTTP_HEADER_WPS_DOCS_AUTHORIZATION = "Wps-Docs-Authorization";
    public final static String HTTP_HEADER_CONTENT_TYPE = "Content-Type";
    public final static String WPS_SIGNATURE_VERSION = "WPS-4";

    public final static String[] WORD_EXT = {"doc","dot","wps","wpt","docx","dotx","docm","dotm","rtf","txt"};
    public final static String[] EXCEL_EXT = {"xls","xlt","et","xlsx","xltx","xlsm","xltm","csv"};
    public final static String[] PPT_EXT = {"ppt","pptx","pptm","ppsx","ppsm","pps","potx","potm","dpt","dps"};
    public final static String[] PDF_EXT = {"pdf", "ofd"};

    public final static String[] X_EXT = {"jpeg","jpg","png","gif","bmp","tif","tiff","svg","psd",
            "tar","zip","7z","gz","rar",
            "md",
            "c","cpp","java","js","css","lrc","h","asm","s","asp","bat","bas","prg","cmd","xml"};
    private static String appId; // 应用id
    private static String secretKey; // 应用秘钥

    public static void initAppInfo(String appId, String secretKey) {
        WPS4Util.appId = appId;
        WPS4Util.secretKey = secretKey;
    }

    /**
     * 根据文件名，获取文件类型
     * @param filename 文件名
     * @return 文件类型 w p s f
     */
    public static String getFileType(String filename){
        if(StringUtils.isEmpty(filename)){
            return null;
        }
        int index = filename.lastIndexOf('.');
        if (index == -1){
            return null;
        }
        String ext = filename.substring(index+1);
        for (String element : WORD_EXT) {
            if (StringUtils.equalsIgnoreCase(ext, element)) {
                return "w";
            }
        }
        for (String item : EXCEL_EXT) {
            if (StringUtils.equalsIgnoreCase(ext, item)) {
                return "s";
            }
        }
        for (String value : PPT_EXT) {
            if (StringUtils.equalsIgnoreCase(ext, value)) {
                return "p";
            }
        }
        for (String s : PDF_EXT) {
            if (StringUtils.equalsIgnoreCase(ext, s)) {
                return "f";
            }
        }
        for (String s : X_EXT) {
            if (StringUtils.equalsIgnoreCase(ext, s)) {
                return "x";
            }
        }
        return null;
    }

    /**
     * 获取请求body MD5
     * @param content 请求body
     * @return
     */
    private static String getContentSha256(String content) {
        if (StringUtils.isBlank(content)) {
            return "";
        } else {
            return DigestUtils.sha256Hex(content);
        }
    }

    /**
     * 获取日期字符串
     *
     * @param date
     * @return
     */
    private static String getGMTDateString(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        return format.format(date);
    }

    /**
     * 获取WPS Authorization
     * @param ver
     * @param httpMethod
     * @param uriWithQuerystring
     * @param contentSha256
     * @param dateString
     * @param contentType
     * @return
     */
    private static String getWpsAuthorization(String ver,String httpMethod,String uriWithQuerystring, String contentSha256, String dateString, String contentType) throws Exception {
        String signatureStr = String.format("%s%s%s%s%s%s",ver,httpMethod,
                uriWithQuerystring,contentType,dateString,contentSha256);
        log.info("要签名的值:{}",signatureStr);
        return String.format("WPS-4 %s:%s",appId,EncryptionUtil.HMACSHA256(signatureStr,secretKey));
    }

    /**
     * 获取签名请求头
     *
     * @param uriWithQuerystring 请求url，带querystring
     * @param content            请求body
     * @param contentType        默认为 application/json
     * @return
     */
    public static Map<String, String> getSignatureHeaders(String uriWithQuerystring,String httpMethod, String content, String contentType) throws Exception {
        if (uriWithQuerystring == null) {
            uriWithQuerystring = "";
        }
        if (contentType == null) {
            contentType = "application/json";
        }
        String contentSha256 = getContentSha256(content);
//        String dateString = "Wed, 10 Aug 2022 03:57:29 GMT";
        String dateString = getGMTDateString(new Date());
        //getGMTDateString(new Date());
        String authorization = getWpsAuthorization(WPS_SIGNATURE_VERSION,httpMethod,
                uriWithQuerystring,contentSha256, dateString, contentType);

        Map<String, String> headers = new HashMap<>();
        headers.put(WPS4Util.HTTP_HEADER_WPS_DOCS_AUTHORIZATION, authorization);
        headers.put(WPS4Util.HTTP_HEADER_CONTENT_TYPE, contentType);
        headers.put(WPS4Util.HTTP_HEADER_WPS_DOCS_DATE, dateString);
        log.info("签名结果: {} -> {}",WPS4Util.HTTP_HEADER_WPS_DOCS_AUTHORIZATION,authorization);
        log.info("签名结果: {} -> {}",WPS4Util.HTTP_HEADER_CONTENT_TYPE,contentType);
        log.info("签名结果: {} -> {}",WPS4Util.HTTP_HEADER_WPS_DOCS_DATE,dateString);
        return headers;
    }

    public static void main(String[] args) throws Exception {
        String contentType = "application/json";
        String uriWithQuerystring = "/api/edit/v1/files/1661841425405/link?type=w";
        String body = "";
        // 获取签名请求头
        String appId = "AKyAYlPgfRjnFBGV";
        String secretKey = "FPLVEBJfEsNVrBkBIShJAmwiufvJIqZy";
        WPS4Util.initAppInfo(appId, secretKey);
        Map<String, String> headers = WPS4Util.getSignatureHeaders(uriWithQuerystring, "GET",body, contentType);
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }

        SimpleDateFormat format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        System.out.println(format.format(new Date()));
    }
}

